# -*- coding: utf-8 -*-
from django.db import connection
from django.contrib.auth.models import User, Permission, Group
from django.contrib.auth.backends import ModelBackend
from django.conf import settings

from ccg.django.auth.ldap_helper import LDAPSearchResult, LDAPHandler
import ldap

 
class NoAuthModelBackend(ModelBackend):
    """Uses the modelbackend but with the authentication method disabled.
       For use when Django permissions are required, but auth should not be used.
    """ 
    def authenticate(self, username=None, password=None):
        return None


class LDAPBackend(object):
    """Presently only supports user auth. No group information is present"""
    def authenticate(self, username=None, password=None):
        if not password:
            print 'Empty password supplied. Access denied'
            return None
        
        user = None
        # anonymous bind to server
        try:
            ld = LDAPHandler()
            l = ld.l
        except ldap.SERVER_DOWN, sd:
            print "LDAP Server is down. Have you set/unset LDAP_DONT_REQUIRE_CERT?:\n%s" % sd
            return None
        except ldap.LDAPError, e:
            print "LDAP Handler Initalisation Exception:\n%s" % e
            return None

        #
        # user test
        #
        userfilter = "(&(objectclass=person) (uid=%s))" % username
        result_data = ld.ldap_query(filter = userfilter, rattrs=['dn'])
        # If the user does not exist in LDAP, Fail.
        if (len(result_data) != 1):
            print 'User didnt exist'
            return None
        # Attempt to bind to the user's DN
        try:
            userdn = result_data[0].get_dn() #userDN of the first result
            l.simple_bind_s(userdn,password)
        except ldap.INVALID_CREDENTIALS, e:
            # Name or password were bad. Fail.
            print "Ldap Exception:\n%s" % e
            return None

        #
        # group membership test
        #
        groupfilter = '(&(objectClass=groupofuniquenames)(uniqueMember=%s)(cn=%s))' % (userdn, ld.GROUP)
        group_result_data = ld.ldap_query(filter=groupfilter, base=ld.GROUP_BASE, rattrs=['cn'])
        # If the group membership does not exist in LDAP, Fail.
        if (len(group_result_data) != 1):
            print 'Member of no groups'
            return None
        #
        # The user existed and authenticated. Get the user
        # record or create one with no privileges.
        #
        try:
            user = User.objects.get(username__exact=username)
        except User.DoesNotExist:

            user = User.objects.create_user(username,"")
            user.is_staff = True
           
            #Attempt to add the user to the default group, but don't worry if it doesn't
            #exist. It is entirely possible that they don't even have a modelbackend.
            try:
                group = Group.objects.get(name__exact=settings.DEFAULT_GROUP)
                user.groups.add(group)
            except Group.DoesNotExist, e:
                print "Group DoesNotExist: %s\n%s" % (settings.DEFAULT_GROUP, e)

            user.save()

        # Success.
        if settings.DEBUG:
            print "Login Success %s" % user
        return user


    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

